home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 25
/
Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso
/
Aminet
/
game
/
shoot
/
ADoom_src_1_2.lha
/
ADoom_src
/
amiga_video.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-08
|
57KB
|
1,732 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <libraries/asl.h>
#include <libraries/lowlevel.h>
#include <cybergraphics/cybergraphics.h>
#include <devices/gameport.h>
#include <devices/timer.h>
#include <devices/keymap.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/layers.h>
#include <proto/intuition.h>
#include <proto/asl.h>
#include <proto/timer.h>
#include <proto/keymap.h>
#include <proto/lowlevel.h>
#include <proto/cybergraphics.h>
#ifdef GRAFFITI
#include "graffiti.h"
#include "graffiti_lib.h"
#include "graffiti_protos.h"
#endif
#include "doomtype.h"
#include "doomdef.h"
#include "doomstat.h"
#include "i_system.h"
#include "i_video.h"
#include "v_video.h"
#include "m_argv.h"
#include "m_bbox.h"
#include "d_main.h"
#include "amiga_median.h"
#include "c2p_020.h"
#include "c2p_030.h"
#include "c2p_040.h"
#include "c2p8_040_amlaukka.h"
#include "amiga_mmu.h"
#include "amiga_sega.h"
#include "r_draw.h"
#include "w_wad.h"
#include "z_zone.h"
/*experimental_c2p_stuff***********************************************/
extern int scaledviewwidth;
void REGARGS (*c2p)(REG(a0, const UBYTE *chunky),
REG(a1, UBYTE *raster),
REG(a2, const UBYTE *chunky_end)) = NULL;
/**********************************************************************/
extern struct ExecBase *SysBase;
struct Library *AslBase = NULL;
struct Library *CyberGfxBase = NULL;
struct Library *LowLevelBase = NULL;
struct Library *KeymapBase = NULL;
extern int cpu_type;
int SCREENWIDTH;
int SCREENHEIGHT;
int weirdaspect;
#define NUMPALETTES 14
static struct ScreenModeRequester *video_smr = NULL;
static struct Screen *video_screen = NULL;
static struct Window *video_window = NULL;
static struct BitMap video_bitmap[3] = {
{0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}},
{0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}},
{0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}}
};
static PLANEPTR video_raster[3] = {NULL, NULL, NULL}; /* contiguous bitplanes */
static UBYTE *video_compare_buffer[3] = {NULL, NULL, NULL}; /* in fastmem */
static struct RastPort video_rastport[3];
static struct ScreenBuffer *video_sb[2] = {NULL, NULL};
static struct DBufInfo *video_db = NULL;
static struct MsgPort *video_mp = NULL;
static int video_which = 0;
static BYTE video_sigbit1 = -1;
static BYTE video_sigbit2 = -1;
static volatile BYTE video_sigbit3 = -1;
static UBYTE *video_chipbuff = NULL;
static struct Task *video_maintask;
static struct Task *video_fliptask = NULL;
static int video_depth = 0;
static int video_oscan_height;
static FAR ULONG video_colourtable[NUMPALETTES][1 + 3*256 + 1];
static int video_palette_index = 0;
static int video_pending_palette_index = 0;
static volatile WORD video_palette_changed = 0;
static UBYTE video_xlate[NUMPALETTES][256]; /* xlate 8-bit to 6-bit EHB */
static BOOL video_is_ehb_mode = FALSE;
static BOOL video_is_native_mode = FALSE;
static BOOL video_is_cyber_mode = FALSE;
static BOOL video_is_using_blitter = FALSE;
static BOOL video_blit_is_in_progress = FALSE;
static BOOL video_use_mmu = FALSE;
static BOOL video_is_directcgx = FALSE;
static BOOL video_doing_fps = FALSE;
static BOOL video_bitmap_is_locked = FALSE;
static APTR video_bitmap_handle;
static int video_f_cache_mode;
static int video_c_cache_mode;
static struct RastPort video_temprp;
static struct BitMap video_tmp_bm = {
0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
static UWORD __chip emptypointer[] = {
0x0000, 0x0000, /* reserved, must be NULL */
0x0000, 0x0000, /* 1 row of image data */
0x0000, 0x0000 /* reserved, must be NULL */
};
/* keyboard */
static BOOL video_is_rawkey;
/* gameport stuff */
static struct MsgPort *gameport_mp = NULL;
static struct IOStdReq *gameport_io = NULL;
static BOOL gameport_is_open = FALSE;
static BOOL gameport_io_in_progress = FALSE;
static struct InputEvent gameport_ie;
static BYTE gameport_ct; /* controller type */
struct GamePortTrigger gameport_gpt = {
GPTF_UPKEYS | GPTF_DOWNKEYS, /* gpt_Keys */
0, /* gpt_Timeout */
1, /* gpt_XDelta */
1 /* gpt_YDelta */
};
/* SEGA variables */
static ULONG prevSega;
static BOOL sega3_selected = FALSE;
static BOOL sega6_selected = FALSE;
#ifdef GRAFFITI
struct Library *GraffitiBase = NULL;
int video_graffiti = 0;
static struct GRF_Screen *video_grf_screen = NULL;
#endif
/****************************************************************************/
struct Library *TimerBase = NULL;
static struct MsgPort *timermp = NULL;
static struct timerequest *timerio = NULL;
static ULONG timerclosed = TRUE;
static ULONG eclocks_per_second; /* EClock frequency in Hz */
static struct EClockVal start_time;
static unsigned int blit_time = 0;
static unsigned int safe_time = 0;
static unsigned int c2p_time = 0;
static unsigned int ccs_time = 0;
static unsigned int wpa8_time = 0;
static unsigned int lock_time = 0;
static unsigned int total_frames = 0;
/****************************************************************************/
static __inline void start_timer (void)
{
ReadEClock (&start_time);
}
/****************************************************************************/
static __inline unsigned int end_timer (void)
{
struct EClockVal end_time;
ReadEClock (&end_time);
return end_time.ev_lo - start_time.ev_lo;
}
/****************************************************************************/
static char *mode_name (ULONG mode)
/* Return a mode name for given mode, compatible with ASL mode requester */
/* Use name in DisplayInfo database if available */
/* else manually construct the name */
{
APTR handle;
char *p;
struct NameInfo nameinfo;
struct DimensionInfo dimsinfo;
static char modename[DISPLAYNAMELEN + 4 + 4 + 11 + 1];
p = modename;
*p = '\0';
if ((handle = FindDisplayInfo (mode & ~SPRITES)) != NULL) {
if (GetDisplayInfoData (handle, (UBYTE *)&nameinfo,
sizeof(nameinfo), DTAG_NAME,
NULL) > sizeof(struct QueryHeader)) {
p += sprintf (p, "%s", nameinfo.Name);
} else if (GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
sizeof(dimsinfo), DTAG_DIMS,
NULL) >= 66 /* sizeof(dimsinfo)*/) {
switch (mode & MONITOR_ID_MASK) {
case DEFAULT_MONITOR_ID:
p += sprintf (p, "DEFAULT:"); /* PAL or NTSC??? */
break;
case NTSC_MONITOR_ID:
p += sprintf (p, "NTSC:");
break;
case PAL_MONITOR_ID:
p += sprintf (p, "PAL:");
break;
case VGA_MONITOR_ID:
p += sprintf (p, "MULTISCAN:");
break;
case A2024_MONITOR_ID:
p += sprintf (p, "A2024:");
break;
case PROTO_MONITOR_ID:
p += sprintf (p, "PROTO:");
break;
case EURO72_MONITOR_ID:
p += sprintf (p, "EURO72:");
break;
case EURO36_MONITOR_ID:
p += sprintf (p, "EURO36:");
break;
case SUPER72_MONITOR_ID:
p += sprintf (p, "SUPER72:");
break;
case DBLNTSC_MONITOR_ID:
p += sprintf (p, "DBLNTSC:");
break;
case DBLPAL_MONITOR_ID:
p += sprintf (p, "DBLPAL:");
break;
default:
p += sprintf (p, "(unknown):");
break;
}
p += sprintf (p, "%d x %d",
dimsinfo.Nominal.MaxX - dimsinfo.Nominal.MinX + 1,
dimsinfo.Nominal.MaxY - dimsinfo.Nominal.MinY + 1);
if ((mode & HAM_KEY) != 0)
p += sprintf (p, " HAM");
if ((mode & EXTRAHALFBRITE_KEY) != 0)
p += sprintf (p, " EHB");
if ((mode & LACE) != 0)
p += sprintf (p, " Interlaced");
} else {
p += sprintf (p, "%s", "(unnamed)");
if ((mode & HAM_KEY) != 0)
p += sprintf (p, " HAM");
if ((mode & EXTRAHALFBRITE_KEY) != 0)
p += sprintf (p, " EHB");
if ((mode & LACE) != 0)
p += sprintf (p, " Interlaced");
}
} else {
p += sprintf (p, "%s", "(unavailable)");
}
return (modename);
}
/****************************************************************************/
static ULONG parse_mode (char *modename)
/* Modename may be descriptive name ("PAL Lores"), or hex ("$00420001" or */
/* "0x12345678") or decimal ("32768"). */
{
ULONG mode, reason;
mode = INVALID_ID;
if (modename != NULL) {
if (modename[0] == '0' && modename[1] == 'x') {
if (sscanf (&modename[2], "%lx", &mode) != 1)
mode = INVALID_ID;
} else if (modename[0] == '$') {
if (sscanf (&modename[1], "%lx", &mode) != 1)
mode = INVALID_ID;
} else if (modename[0] >= '0' && modename[0] <= '9') {
if (sscanf (modename, "%ld", &mode) != 1)
mode = INVALID_ID;
} else {
while ((mode = NextDisplayInfo (mode)) != INVALID_ID) {
if ((mode & LORESDPF_KEY) == 0) {
/* printf ("$%08x \"%s\"\n", mode, mode_name (mode)); */
if (strcmp (mode_name (mode), modename) == 0)
break;
}
}
}
}
if (FindDisplayInfo (mode) == NULL)
I_Error ("ScreenMode not in database: \"%s\"", modename);
if ((reason = ModeNotAvailable (mode)) != 0)
I_Error ("Mode $%08x is not available: %ld", mode, reason);
return (mode);
}
/**********************************************************************/
static void video_do_fps (struct RastPort *rp, int yoffset)
{
ULONG x;
static struct EClockVal start_time = {0, 0};
struct EClockVal end_time;
char msg[4];
ReadEClock (&end_time);
x = end_time.ev_lo - start_time.ev_lo;
if (x != 0) {
x = (eclocks_per_second + (x >> 1)) / x; /* round to nearest */
msg[0] = (x % 1000) / 100 + '0';
msg[1] = (x % 100) / 10 + '0';
msg[2] = (x % 10) + '0';
msg[3] = '\0';
Move (rp, SCREENWIDTH - 24, yoffset + 6);
Text (rp, msg, 3);
}
start_time = end_time;
}
/**********************************************************************/
// This asynchronous task waits in a loop for sigbit3 signals.
// Sigbit3 is signalled when the next frame is just finished.
// Sigbit3 may be signalled from the qblit() cleanup function or from the
// main task.
// On sigbit3, we load the new palette and call ChangeScreenBuffer().
// This way there is no delay calling ChangeScreenBuffer() after the last blit
// has finished.
// The main 3D rendering task may be interrupted to call ChangeScreenBuffer()
// SIGBREAKF_CTRL_F and SIGBREAKF_CTRL_C are used for synchronisation
// with the main task.
static void __saveds __interrupt video_flipscreentask (void)
{
ULONG sig;
struct MsgPort *video_dispport, *video_safeport;
BOOL going, video_disp, video_safe;
int i;
video_sigbit3 = AllocSignal(-1);
Signal (video_maintask, SIGBREAKF_CTRL_F);
video_dispport = CreatePort (NULL, 0);
video_safeport = CreatePort (NULL, 0);
video_disp = TRUE;
video_safe = TRUE;
for (i = 0; i < 2; i++) {
video_sb[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = video_dispport;
video_sb[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = video_safeport;
}
going = (video_sigbit3 != -1) &&
(video_dispport != NULL) &&
(video_safeport != NULL);
while (going) {
sig = Wait (1 << video_sigbit3 | SIGBREAKF_CTRL_C);
if ((sig & (1 << video_sigbit3)) != 0) {
if (video_doing_fps)
video_do_fps (&video_rastport[video_which], 0);
if (video_palette_changed > 0) {
LoadRGB32 (&video_screen->ViewPort,
video_colourtable[video_palette_index]);
video_palette_changed--; /* keep it set for 2 frames for dblbuffing */
}
if ((ChangeScreenBuffer (video_screen, video_sb[video_which])) != 0) {
video_disp = FALSE;
video_safe = FALSE;
}
if (!video_safe) { /* wait until safe */
Wait (1 << video_safeport->mp_SigBit);
while (GetMsg (video_safeport) != NULL) /* clear message queue */
/* do nothing */ ;
video_safe = TRUE;
}
Signal (video_maintask, SIGBREAKF_CTRL_F);
if (!video_disp) { /* wait for previous frame to be displayed */
Wait (1 << video_dispport->mp_SigBit);
while (GetMsg (video_dispport) != NULL) /* clear message queue */
/* do nothing */ ;
video_disp = TRUE;
}
}
if ((sig & SIGBREAKF_CTRL_C) != 0) {
going = FALSE;
}
}
if (!video_safe) { /* wait for safe */
Wait (1 << video_safeport->mp_SigBit);
while (GetMsg (video_safeport) != NULL) /* clear message queue */
/* do nothing */ ;
video_safe = TRUE;
}
if (!video_disp) { /* wait for last frame to be displayed */
Wait (1 << video_dispport->mp_SigBit);
while (GetMsg (video_dispport) != NULL) /* clear message queue */
/* do nothing */ ;
video_disp = TRUE;
}
if (video_sigbit3 != -1)
FreeSignal (video_sigbit3);
if (video_dispport != NULL)
DeletePort (video_dispport);
if (video_safeport != NULL)
DeletePort (video_safeport);
Signal (video_maintask, SIGBREAKF_CTRL_F);
Wait (0);
}
/**********************************************************************/
// Called by D_DoomMain,
// determines the hardware configuration
// and sets up the video mode
void I_InitGraphics (void)
{
int i;
ULONG propertymask, idcmp, wflags, width, pixfmt;
struct Rectangle rect;
char reqtitle[32];
int mode, depth, nbytes, p;
DisplayInfoHandle handle;
struct DisplayInfo dispinfo;
struct DimensionInfo dimsinfo;
static struct TextAttr topaz8 = {
"topaz.font", 8, FS_NORMAL, FPF_ROMFONT
};
video_maintask = FindTask(NULL);
if ((KeymapBase = OpenLibrary ("keymap.library", 0)) == NULL)
I_Error ("Can't open keymap.library");
if ((timermp = CreatePort (NULL, 0)) == NULL)
I_Error ("Can't create messageport!");
if ((timerio = (struct timerequest *)CreateExtIO (timermp,
sizeof(struct timerequest))) == NULL)
I_Error ("Can't create External IO!");
if (timerclosed = OpenDevice (TIMERNAME, UNIT_ECLOCK,
(struct IORequest *)timerio, 0))
I_Error ("Can't open timer.device!");
TimerBase = (struct Library *)timerio->tr_node.io_Device;
eclocks_per_second = ReadEClock (&start_time);
video_doing_fps = M_CheckParm ("-fps");
#ifdef GRAFFITI
if (video_graffiti != 0) {
if ((GraffitiBase = OpenLibrary ("graffiti.library", 0)) == NULL)
I_Error ("Can't open graffiti.library");
if ((video_grf_screen = OpenChunkyScreen (video_graffiti)) == NULL)
I_Error ("graffiti.library OpenChunkyScreen() failed");
video_screen = (struct Screen *)video_grf_screen->GRF_ScreenID;
video_depth = 8;
} else {
#endif
if (AslBase == NULL) {
if ((AslBase = OpenLibrary ("asl.library", 37L)) == NULL ||
(video_smr = AllocAslRequestTags (ASL_ScreenModeRequest, TAG_DONE)) == NULL) {
I_Error ("OpenLibrary(""asl.library"", 37) failed");
}
}
CyberGfxBase = OpenLibrary ("cybergraphics.library", 0); /* may be NULL */
/* first check tooltypes for SCREENMODE */
mode = -1;
p = M_CheckParm ("-screenmode");
if (p && p < myargc - 1) {
mode = parse_mode (myargv[p+1]);
}
/* if not found in icon tooltypes, then put up a ScreenMode requester */
if (mode == -1) {
propertymask = /* DIPF_IS_EXTRAHALFBRITE | */ DIPF_IS_DUALPF |
DIPF_IS_PF2PRI | DIPF_IS_HAM;
if (CyberGfxBase != NULL)
mode = BestCModeIDTags (CYBRBIDTG_NominalWidth, SCREENWIDTH,
CYBRBIDTG_NominalHeight, SCREENHEIGHT,
CYBRBIDTG_Depth, 8,
TAG_DONE);
else if (GfxBase->LibNode.lib_Version >= 39)
mode = BestModeID (BIDTAG_NominalWidth, SCREENWIDTH,
BIDTAG_NominalHeight, SCREENHEIGHT,
BIDTAG_Depth, video_depth,
BIDTAG_DIPFMustNotHave, propertymask,
TAG_DONE);
else
mode = EXTRAHALFBRITE_KEY;
if (AslBase->lib_Version >= 38) {
sprintf (reqtitle, "ADoom %dx%d", SCREENWIDTH, SCREENHEIGHT);
if (!AslRequestTags (video_smr,
ASLSM_TitleText, (ULONG)reqtitle,
ASLSM_InitialDisplayID, mode,
ASLSM_MinWidth, SCREENWIDTH,
ASLSM_MinHeight, SCREENHEIGHT,
ASLSM_MaxWidth, MAXSCREENWIDTH,
ASLSM_MaxHeight, MAXSCREENHEIGHT,
ASLSM_MinDepth, 6,
ASLSM_MaxDepth, 8,
ASLSM_PropertyMask, propertymask,
ASLSM_PropertyFlags, 0,
TAG_DONE)) {
I_Error ("AslRequest() failed");
}
mode = video_smr->sm_DisplayID;
}
}
if ((handle = FindDisplayInfo (mode)) == NULL) {
I_Error ("Can't FindDisplayInfo() for mode %08x", mode);
}
if ((nbytes = GetDisplayInfoData (handle, (UBYTE *)&dispinfo,
sizeof(struct DisplayInfo), DTAG_DISP,
NULL)) < 40 /*sizeof(struct DisplayInfo)*/) {
I_Error ("Can't GetDisplayInfoData() for mode %08x, got %d bytes",
mode, nbytes);
}
if ((nbytes = GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
sizeof(dimsinfo), DTAG_DIMS,
NULL)) < 66 /* sizeof(dimsinfo)*/) {
I_Error ("Can't GetDisplayInfoData() for mode %08x, got %d bytes",
mode, nbytes);
}
video_oscan_height = dimsinfo.MaxOScan.MaxY - dimsinfo.MaxOScan.MinY + 1;
video_is_cyber_mode = 0;
if (CyberGfxBase != NULL)
video_is_cyber_mode = IsCyberModeID (mode);
/* this test needs improving */
video_is_native_mode = ((GfxBase->LibNode.lib_Version < 39 ||
(dispinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE) != 0 ||
(dispinfo.PropertyFlags & DIPF_IS_AA) != 0 ||
(dispinfo.PropertyFlags & DIPF_IS_ECS) != 0 ||
(dispinfo.PropertyFlags & DIPF_IS_DBUFFER) != 0) &&
!video_is_cyber_mode &&
(dispinfo.PropertyFlags & DIPF_IS_FOREIGN) == 0);
video_is_ehb_mode = ((dispinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE) != 0);
/* manual overrides */
if (M_CheckParm ("-rtg"))
video_is_native_mode = FALSE;
else if (M_CheckParm ("-native"))
video_is_native_mode = TRUE;
if (M_CheckParm ("-ehb"))
video_is_ehb_mode = TRUE;
printf ("Screen Mode $%08x is ", mode);
if (video_is_native_mode)
printf (" NATIVE-PLANAR");
else
printf (" FOREIGN");
if (video_is_ehb_mode)
printf (" EXTRAHALFBRITE");
else
printf (" 8-BIT");
if (video_is_cyber_mode)
printf (" CYBERGRAPHX");
printf ("\n");
if (video_is_ehb_mode)
video_depth = 6;
else
video_depth = 8;
rect.MinX = 0;
rect.MinY = 0;
rect.MaxX = SCREENWIDTH - 1;
rect.MaxY = SCREENHEIGHT - 1;
if (M_CheckParm ("-mmu") && cpu_type >= 68040)
video_use_mmu = true;
if (video_is_native_mode) {
video_is_using_blitter = (cpu_type < 68040);
for (i = 0; i < (video_is_using_blitter ? 2 : 3); i++) {
/* use the mmu hack only if cpu is 68040+ and user specified -mmu */
if (video_use_mmu) {
ULONG *ptr, mem;
mem = (ULONG)AllocVec (SCREENWIDTH * SCREENHEIGHT / 8 * video_depth +
4100, MEMF_CHIP);
if (!mem)
I_Error ("AllocVec() failed");
ptr = (ULONG*)((mem & ~0xfff) + 4096);
ptr[-1] = 4096 - (mem & 0xfff);
video_raster[i] = (byte *)ptr;
video_c_cache_mode = mmu_mark (video_raster[i],
SCREENWIDTH * SCREENHEIGHT / 8 * video_depth,
CM_IMPRECISE, SysBase);
} else {
if ((video_raster[i] = (PLANEPTR)AllocRaster (SCREENWIDTH,
video_depth * SCREENHEIGHT)) == NULL)
I_Error ("AllocRaster() failed");
}
memset (video_raster[i], 0, video_depth * RASSIZE (SCREENWIDTH, SCREENHEIGHT));
InitBitMap (&video_bitmap[i], video_depth, SCREENWIDTH, SCREENHEIGHT);
for (depth = 0; depth < video_depth; depth++)
video_bitmap[i].Planes[depth] = video_raster[i] +
depth * RASSIZE (SCREENWIDTH, SCREENHEIGHT);
InitRastPort (&video_rastport[i]);
video_rastport[i].BitMap = &video_bitmap[i];
SetAPen (&video_rastport[i], (1 << video_depth) - 1);
SetBPen (&video_rastport[i], 0);
SetDrMd (&video_rastport[i], JAM2);
}
/* experimental c2p stuff */
if (!video_is_using_blitter)
c2p = c2p8_reloc (screens[0], &video_bitmap[0], SysBase);
if ((video_screen = OpenScreenTags (NULL,
SA_Type, CUSTOMSCREEN | CUSTOMBITMAP,
SA_DisplayID, mode,
SA_DClip, (ULONG)&rect,
SA_Width, SCREENWIDTH,
SA_Height, SCREENHEIGHT,
SA_Depth, video_depth,
SA_Font, &topaz8,
/* SA_Draggable,FALSE, */
/* SA_AutoScroll,FALSE, */
/* SA_Exclusive,TRUE, */
SA_Quiet, TRUE,
SA_BitMap, &video_bitmap[0], /* custom bitmap, contiguous planes */
TAG_DONE, 0)) == NULL) {
I_Error ("OpenScreen() failed");
}
for (i = 0; i < (video_is_using_blitter ? 2 : 3); i++) {
if ((video_compare_buffer[i] = malloc (SCREENWIDTH * SCREENHEIGHT)) == NULL)
I_Error ("Out of memory allocating %d bytes", SCREENWIDTH * SCREENHEIGHT);
memset (video_compare_buffer[i], 0, SCREENWIDTH * SCREENHEIGHT);
}
if (video_is_using_blitter) {
for (i = 0; i < 2; i++) {
if ((video_sb[i] = AllocScreenBuffer (video_screen, &video_bitmap[i], 0)) == NULL)
I_Error ("Can't allocate structure for double buffering");
}
} else {
video_db = AllocDBufInfo (&video_screen->ViewPort);
video_mp = CreateMsgPort ();
if (!video_db || !video_mp)
I_Error ("Can't allocate dbuffer information");
video_db->dbi_DispMessage.mn_ReplyPort = video_mp;
video_which = 1;
ChangeVPBitMap (&video_screen->ViewPort, &video_bitmap[0], video_db);
}
} else { /* non-native ScreenMode */
if (video_is_cyber_mode && M_CheckParm ("-directcgx"))
video_is_directcgx = TRUE;
if ((video_screen = OpenScreenTags (NULL,
SA_Type, CUSTOMSCREEN,
SA_DisplayID, mode,
SA_DClip, (ULONG)&rect,
SA_Width, SCREENWIDTH,
SA_Height, video_is_directcgx ? video_oscan_height << 1
: SCREENHEIGHT,
SA_Depth, video_depth,
SA_Font, &topaz8,
/* SA_Draggable,FALSE, */
/* SA_AutoScroll,FALSE, */
/* SA_Exclusive,TRUE, */
SA_Quiet, TRUE,
TAG_DONE, 0)) == NULL) {
I_Error ("OpenScreen() failed");
}
}
if (video_is_directcgx) {
video_bitmap_handle = LockBitMapTags (video_screen->ViewPort.RasInfo->BitMap,
LBMI_WIDTH, &width,
LBMI_DEPTH, &depth,
LBMI_PIXFMT, &pixfmt,
LBMI_BASEADDRESS, &screens[0],
TAG_DONE);
UnLockBitMap (video_bitmap_handle);
if (/* width != SCREENWIDTH || */
depth != video_depth ||
pixfmt != PIXFMT_LUT8) {
I_Error ("ScreenMode of width %d, depth %d, pixfmt %d cannot be used with -directcgx",
width, depth, pixfmt);
}
} else {
if (video_use_mmu) {
video_f_cache_mode = mmu_mark (screens[0],
(SCREENWIDTH * SCREENHEIGHT + 4096) & ~0xfff,
CM_WRITETHROUGH, SysBase);
}
}
#ifdef GRAFFITI
}
#endif
idcmp = IDCMP_RAWKEY;
wflags = WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_NOCAREREFRESH |
WFLG_SIMPLE_REFRESH;
if (M_CheckParm("-mouse") != NULL) {
idcmp |= IDCMP_MOUSEMOVE | IDCMP_DELTAMOVE | IDCMP_MOUSEBUTTONS;
wflags |= WFLG_REPORTMOUSE;
}
if ((video_window = OpenWindowTags (NULL,
WA_Left, 0,
WA_Top, 0,
WA_Width, video_graffiti != 0 ? 640 : SCREENWIDTH,
WA_Height, video_is_directcgx ? video_oscan_height << 1
: SCREENHEIGHT,
WA_IDCMP, idcmp,
WA_Flags, wflags,
WA_CustomScreen, video_screen,
TAG_DONE)) == NULL) {
I_Error ("OpenWindow() failed");
}
InitBitMap (&video_tmp_bm, video_depth, SCREENWIDTH, 1);
for (depth = 0; depth < video_depth; depth++)
if ((video_tmp_bm.Planes[depth] = (PLANEPTR)AllocRaster (SCREENWIDTH, 1)) == NULL)
I_Error ("AllocRaster() failed");
video_temprp = *video_window->RPort;
video_temprp.Layer = NULL;
video_temprp.BitMap = &video_tmp_bm;
if (video_is_native_mode) {
if (video_is_using_blitter) {
if ((video_sigbit1 = AllocSignal(-1)) == -1 ||
(video_sigbit2 = AllocSignal(-1)) == -1)
I_Error ("Can't allocate signal!\n");
Signal (video_maintask, (1 << video_sigbit1) | (1 << video_sigbit2));
/* initial state is finished */
if ((video_fliptask = CreateTask ("ADoom_flipscreen", 100,
video_flipscreentask, 4096)) == NULL)
I_Error ("Can't create subtask");
Wait (SIGBREAKF_CTRL_F);
if (video_sigbit3 == -1)
I_Error ("Subtask couldn't allocate sigbit");
if ((video_chipbuff = AllocMem (2 * SCREENWIDTH * SCREENHEIGHT,
MEMF_CHIP | MEMF_CLEAR)) == NULL)
I_Error ("Out of CHIP memory allocating %d bytes",
2 * SCREENWIDTH * SCREENHEIGHT);
if (!video_is_ehb_mode)
c2p1x1_cpu3blit1_queue_init (SCREENWIDTH, SCREENHEIGHT, 0,
SCREENWIDTH * SCREENHEIGHT / 8,
1 << video_sigbit1, 1 << video_sigbit3,
video_maintask, video_fliptask,
video_chipbuff);
}
}
if (!M_CheckParm ("-mousepointer"))
SetPointer (video_window, emptypointer, 1, 16, 0, 0);
I_RecalcPalettes ();
/* keyboard & joystick initialisation */
video_is_rawkey = M_CheckParm ("-rawkey");
if (M_CheckParm ("-sega3") != NULL)
sega3_selected = TRUE;
if (M_CheckParm ("-sega6") != NULL)
sega6_selected = TRUE;
if (M_CheckParm ("-joypad") != NULL) {
if ((LowLevelBase = OpenLibrary ("lowlevel.library", 0)) == NULL)
I_Error ("-joypad option specified and can't open lowlevel.library");
} else {
if ((gameport_mp = CreatePort (NULL, 0)) == NULL ||
(gameport_io = (struct IOStdReq *)CreateExtIO (gameport_mp,
sizeof(struct IOStdReq))) == NULL ||
OpenDevice ("gameport.device", 1, (struct IORequest *)gameport_io, 0) != 0)
I_Error ("Can't open gameport.device");
gameport_is_open = TRUE;
Forbid ();
gameport_io->io_Command = GPD_ASKCTYPE;
gameport_io->io_Length = 1;
gameport_io->io_Data = &gameport_ct;
DoIO ((struct IORequest *)gameport_io);
if (gameport_ct != GPCT_NOCONTROLLER) {
Permit ();
fprintf (stderr, "Another task is using the gameport! Joystick disabled");
CloseDevice ((struct IORequest *)gameport_io);
gameport_is_open = FALSE;
} else {
gameport_ct = GPCT_ABSJOYSTICK;
gameport_io->io_Command = GPD_SETCTYPE;
gameport_io->io_Length = 1;
gameport_io->io_Data = &gameport_ct;
DoIO ((struct IORequest *)gameport_io);
Permit ();
gameport_io->io_Command = GPD_SETTRIGGER;
gameport_io->io_Length = sizeof(struct GamePortTrigger);
gameport_io->io_Data = &gameport_gpt;
DoIO ((struct IORequest *)gameport_io);
gameport_io->io_Command = GPD_READEVENT;
gameport_io->io_Length = sizeof (struct InputEvent);
gameport_io->io_Data = &gameport_ie;
SendIO ((struct IORequest *)gameport_io);
gameport_io_in_progress = TRUE;
}
}
}
/**********************************************************************/
void I_ShutdownGraphics (void)
{
int depth, i;
if (video_is_directcgx && video_bitmap_is_locked) {
UnLockBitMap (video_bitmap_handle);
video_bitmap_is_locked = FALSE;
}
if (LowLevelBase != NULL) {
CloseLibrary (LowLevelBase);
LowLevelBase = NULL;
}
if (gameport_io_in_progress) {
AbortIO ((struct IORequest *)gameport_io);
WaitIO ((struct IORequest *)gameport_io);
gameport_io_in_progress = FALSE;
gameport_ct = GPCT_NOCONTROLLER;
gameport_io->io_Command = GPD_SETCTYPE;
gameport_io->io_Length = 1;
gameport_io->io_Data = &gameport_ct;
DoIO ((struct IORequest *)gameport_io);
}
if (gameport_is_open) {
CloseDevice ((struct IORequest *)gameport_io);
gameport_is_open = FALSE;
}
if (gameport_io != NULL) {
DeleteExtIO ((struct IORequest *)gameport_io);
gameport_io = NULL;
}
if (gameport_mp != NULL) {
DeletePort (gameport_mp);
gameport_mp = NULL;
}
if (video_blit_is_in_progress) {
Wait (SIGBREAKF_CTRL_F);
video_blit_is_in_progress = FALSE;
}
if (video_fliptask != NULL) {
Signal (video_fliptask, SIGBREAKF_CTRL_C);
Wait (SIGBREAKF_CTRL_F);
DeleteTask (video_fliptask);
video_fliptask = NULL;
}
if (video_is_using_blitter) {
if (video_sigbit1 != -1) {
Wait (1 << video_sigbit1); // wait for last c2p8 to finish pass 3
FreeSignal (video_sigbit1);
video_sigbit1 = -1;
}
if (video_sigbit2 != -1) {
Wait (1 << video_sigbit2); // wait for last c2p8 to completely finish
FreeSignal (video_sigbit2);
video_sigbit2 = -1;
}
}
if (video_window != NULL) {
ClearPointer (video_window);
CloseWindow (video_window);
video_window = NULL;
}
if (video_is_using_blitter) {
for (i = 0; i < 2; i++) {
if (video_sb[i] != NULL) {
FreeScreenBuffer (video_screen, video_sb[i]);
video_sb[i] = NULL;
}
}
} else {
if (video_mp) {
WaitPort (video_mp);
while (GetMsg(video_mp));
DeleteMsgPort (video_mp);
video_mp = NULL;
}
if (video_db) {
FreeDBufInfo (video_db);
video_db = NULL;
}
}
#ifdef GRAFFITI
if (video_grf_screen != NULL) {
CloseChunkyScreen (video_grf_screen);
video_grf_screen = NULL;
video_screen = NULL;
}
if (GraffitiBase != NULL) {
CloseLibrary (GraffitiBase);
GraffitiBase = NULL;
}
#endif
if (video_screen != NULL) {
CloseScreen (video_screen);
video_screen = NULL;
}
for (depth = 0; depth < video_depth; depth++) {
if (video_tmp_bm.Planes[depth] != NULL) {
FreeRaster (video_tmp_bm.Planes[depth], SCREENWIDTH, 1);
video_tmp_bm.Planes[depth] = NULL;
}
}
if (video_chipbuff != NULL) {
FreeMem (video_chipbuff, 2 * SCREENWIDTH * SCREENHEIGHT);
video_chipbuff = NULL;
}
for (i = 0; i < (video_is_using_blitter ? 2 : 3); i++) {
if (video_raster[i] != NULL) {
if (video_use_mmu) {
ULONG *ptr = (ULONG *)video_raster[i];
UBYTE *p2 = (UBYTE *)ptr;
mmu_mark (video_raster[i], SCREENWIDTH * SCREENHEIGHT / 8 * video_depth,
video_c_cache_mode, SysBase);
FreeVec (p2 - ptr[-1]);
} else
FreeRaster (video_raster[i], SCREENWIDTH, video_depth * SCREENHEIGHT);
video_raster[i] = NULL;
}
if (video_compare_buffer[i] != NULL) {
free (video_compare_buffer[i]);
video_compare_buffer[i] = NULL;
}
}
if (video_use_mmu && !video_is_directcgx) {
if (screens[0] != NULL)
mmu_mark (screens[0], (SCREENWIDTH * SCREENHEIGHT + 4096) & ~0xfff,
video_f_cache_mode, SysBase);
}
if (KeymapBase == NULL) {
CloseLibrary (KeymapBase);
KeymapBase = NULL;
}
if (CyberGfxBase == NULL) {
CloseLibrary (CyberGfxBase);
CyberGfxBase = NULL;
}
/* experimental c2p stuff */
if (c2p && !video_is_using_blitter) {
c2p8_deinit (c2p, SysBase);
c2p = NULL;
}
if (!timerclosed) {
if (!CheckIO((struct IORequest *)timerio)) {
AbortIO ((struct IORequest *)timerio);
WaitIO ((struct IORequest *)timerio);
}
CloseDevice ((struct IORequest *)timerio);
timerclosed = TRUE;
TimerBase = NULL;
}
if (timerio != NULL) {
DeleteExtIO ((struct IORequest *)timerio);
timerio = NULL;
}
if (timermp != NULL) {
DeletePort (timermp);
timermp = NULL;
}
}
/**********************************************************************/
// recalculate colourtable[][] after changing usegamma
void I_RecalcPalettes (void)
{
int p, i;
byte *palette;
static UBYTE gpalette[3*256];
static int lu_palette;
lu_palette = W_GetNumForName ("PLAYPAL");
for (p = 0; p < NUMPALETTES; p++) {
palette = (byte *) W_CacheLumpNum (lu_palette, PU_STATIC)+p*768;
if (video_is_ehb_mode) {
i = 3 * 256 - 1;
do {
gpalette[i] = gammatable[usegamma][palette[i]];
} while (--i >= 0);
video_colourtable[p][0] = (32 << 16) + 0;
median_cut (gpalette, &video_colourtable[p][1], video_xlate[p]);
video_colourtable[p][33] = 0;
} else {
#ifdef GRAFFITI
if (video_graffiti != 0) {
for (i = 0; i < 256; i++)
video_colourtable[p][i] =
(((UBYTE)gammatable[usegamma][palette[3*i+0]]) << 16) +
(((UBYTE)gammatable[usegamma][palette[3*i+1]]) << 8) +
((UBYTE)gammatable[usegamma][palette[3*i+2]]);
} else {
#endif
i = 3 * 256 - 1;
video_colourtable[p][i + 2] = 0;
do {
// Better to define c locally here instead of for the whole function:
ULONG c = gammatable[usegamma][palette[i]];
c += (c << 8);
video_colourtable[p][i + 1] = (c << 16) + c;
} while (--i >= 0);
video_colourtable[p][0] = (256 << 16) + 0;
#ifdef GRAFFITI
}
#endif
}
}
}
/**********************************************************************/
// Takes full 8 bit values.
void I_SetPalette (byte *palette, int palette_index)
{
if (video_is_ehb_mode)
if (video_is_using_blitter) {
video_palette_changed = 2; /* double buffering */
video_pending_palette_index = palette_index;
} else {
video_palette_changed = 3; /* triple buffering */
video_palette_index = palette_index;
}
else {
video_palette_changed = 1;
video_palette_index = palette_index;
}
}
/**********************************************************************/
// Called by anything that renders to screens[0] (except 3D view)
void I_MarkRect (int left, int top, int width, int height)
{
M_AddToBox (dirtybox, left, top);
M_AddToBox (dirtybox, left + width - 1, top + height - 1);
}
/**********************************************************************/
void I_StartUpdate (void)
{
UBYTE *base_address;
if (video_is_directcgx) {
if (video_palette_changed != 0) {
LoadRGB32 (&video_screen->ViewPort,
video_colourtable[video_palette_index]);
video_palette_changed = 0;
}
if (!video_bitmap_is_locked) {
start_timer ();
video_bitmap_handle = LockBitMapTags (video_screen->ViewPort.RasInfo->BitMap,
LBMI_BASEADDRESS, &base_address,
TAG_DONE);
lock_time += end_timer ();
video_bitmap_is_locked = TRUE;
video_which = 1 - video_which;
if (video_which != 0)
screens[0] = base_address + (SCREENWIDTH * video_oscan_height);
else
screens[0] = base_address;
R_InitBuffer (scaledviewwidth, viewheight); /* recalc ylookup2[] */
}
}
}
/**********************************************************************/
void I_UpdateNoBlit (void)
{
}
/**********************************************************************/
void I_FinishUpdate (void)
/* This needs optimising to copy just the parts that changed,
especially if the user has shrunk the playscreen. */
{
int top, left, width, height;
total_frames++;
#ifdef GRAFFITI
if (video_graffiti != 0) {
start_timer();
CopyChunkyScreen (video_grf_screen, screens[0]);
SetChunkyPalette (video_grf_screen,
(long *)video_colourtable[video_palette_index]);
video_palette_changed = 0;
ccs_time += end_timer();
return;
}
#endif
if (video_is_directcgx) {
if (video_bitmap_is_locked) {
UnLockBitMap (video_bitmap_handle);
video_bitmap_is_locked = FALSE;
video_screen->ViewPort.RasInfo->RyOffset = video_which != 0 ?
video_oscan_height : 0;
ScrollVPort (&video_screen->ViewPort);
/* copy dirtybox into other buffer, hopefully using gfx-card blitter!? */
if (dirtybox[BOXRIGHT] >= dirtybox[BOXLEFT] &&
dirtybox[BOXTOP] >= dirtybox[BOXBOTTOM])
if (video_which != 0)
ClipBlit (video_window->RPort,
dirtybox[BOXLEFT], video_oscan_height + dirtybox[BOXBOTTOM],
video_window->RPort,
dirtybox[BOXLEFT], dirtybox[BOXBOTTOM],
dirtybox[BOXRIGHT] - dirtybox[BOXLEFT] + 1,
dirtybox[BOXTOP] - dirtybox[BOXBOTTOM] + 1,
0xc0);
else
ClipBlit (video_window->RPort,
dirtybox[BOXLEFT], dirtybox[BOXBOTTOM],
video_window->RPort,
dirtybox[BOXLEFT], video_oscan_height + dirtybox[BOXBOTTOM],
dirtybox[BOXRIGHT] - dirtybox[BOXLEFT] + 1,
dirtybox[BOXTOP] - dirtybox[BOXBOTTOM] + 1,
0xc0);
M_ClearBox (dirtybox);
} else
I_Error ("I_FinishUpdate() called without calling I_StartUpdate() first");
if (video_doing_fps)
video_do_fps (video_window->RPort,
video_which != 0 ? video_oscan_height : 0);
return;
}
/* update only the viewwindow and dirtybox when gamestate == GS_LEVEL */
if (gamestate == GS_LEVEL) {
if (dirtybox[BOXLEFT] < viewwindowx)
left = dirtybox[BOXLEFT];
else
left = viewwindowx;
if (dirtybox[BOXRIGHT] + 1 > viewwindowx + scaledviewwidth)
width = dirtybox[BOXRIGHT] + 1 - left;
else
width = viewwindowx + scaledviewwidth - left;
if (dirtybox[BOXBOTTOM] < viewwindowy) /* BOXBOTTOM is really the top! */
top = dirtybox[BOXBOTTOM];
else
top = viewwindowy;
if (dirtybox[BOXTOP] + 1 > viewwindowy + viewheight)
height = dirtybox[BOXTOP] + 1 - top;
else
height = viewwindowy + viewheight - top;
M_ClearBox (dirtybox);
#ifdef RANGECHECK
if (left < 0 || left + width > SCREENWIDTH ||
top < 0 || top + height > SCREENHEIGHT)
I_Error ("I_FinishUpdate: Box out of range: %d %d %d %d",
left, top, width, height);
#endif
} else {
left = 0;
top = 0;
width = SCREENWIDTH;
height = SCREENHEIGHT;
}
if (video_is_native_mode) {
if (video_is_using_blitter) {
start_timer();
Wait (1 << video_sigbit1); /* wait for prev c2p() to finish pass 3 */
blit_time += end_timer();
if (video_blit_is_in_progress) {
start_timer();
Wait (SIGBREAKF_CTRL_F); /* wait for prev ChangeScreenBuffer() safe */
safe_time += end_timer();
video_blit_is_in_progress = FALSE;
}
video_which = 1 - video_which; /* render to the hidden bitmap */
start_timer();
if (video_is_ehb_mode) {
video_palette_index = video_pending_palette_index;
c2p_6_020 (&screens[0][SCREENWIDTH * top],
video_bitmap[video_which].Planes,
1 << video_sigbit1, 1 << video_sigbit2, 1 << video_sigbit3,
SCREENWIDTH * height, (SCREENWIDTH >> 3) * top,
video_xlate[video_palette_index], video_fliptask,
video_chipbuff);
} else {
if (cpu_type < 68030)
c2p_8_020 (&screens[0][SCREENWIDTH * top],
video_bitmap[video_which].Planes,
1 << video_sigbit1, 1 << video_sigbit2, 1 << video_sigbit3,
SCREENWIDTH * height, (SCREENWIDTH >> 3) * top,
video_fliptask, video_chipbuff);
else
c2p1x1_cpu3blit1_queue (screens[0], video_raster[video_which]);
}
c2p_time += end_timer();
video_blit_is_in_progress = TRUE;
} else {
start_timer();
if (video_is_ehb_mode) {
c2p_6_040 (screens[0], video_raster[video_which],
video_compare_buffer[video_which],
video_xlate[video_palette_index],
(SCREENWIDTH * SCREENHEIGHT) >> 3,
video_palette_changed);
if (video_palette_changed > 0) {
if (video_palette_changed == 3)
LoadRGB32 (&video_screen->ViewPort,
video_colourtable[video_palette_index]);
video_palette_changed--;
}
} else {
if (c2p && scaledviewwidth >= SCREENWIDTH-64)
c2p (screens[0], video_raster[video_which],
screens[0] + SCREENWIDTH * SCREENHEIGHT);
else
c2p_8_040 (screens[0], video_raster[video_which],
video_compare_buffer[video_which],
(SCREENWIDTH * SCREENHEIGHT) >> 3);
if (video_palette_changed != 0) {
LoadRGB32 (&video_screen->ViewPort,
video_colourtable[video_palette_index]);
video_palette_changed = 0;
}
}
c2p_time += end_timer();
if (video_doing_fps)
video_do_fps (&video_rastport[video_which], 0);
WaitPort (video_mp);
while (GetMsg (video_mp))
/* do nothing */ ;
ChangeVPBitMap (&video_screen->ViewPort, &video_bitmap[video_which],
video_db);
if (++video_which == 3)
video_which = 0;
}
} else { /* non-native ScreenMode */
if (video_palette_changed != 0) {
LoadRGB32 (&video_screen->ViewPort,
video_colourtable[video_palette_index]);
video_palette_changed = 0;
}
start_timer();
if (GfxBase->LibNode.lib_Version >= 40)
WriteChunkyPixels (video_window->RPort, left, top, left+width-1,
top+height-1, &screens[0][SCREENWIDTH * top + left],
SCREENWIDTH);
else
WritePixelArray8 (video_window->RPort, 0, top, SCREENWIDTH-1,
top+height-1, &screens[0][SCREENWIDTH * top],
&video_temprp);
wpa8_time += end_timer();
if (video_doing_fps)
video_do_fps (video_window->RPort, 0);
}
}
/**********************************************************************/
// Wait for vertical retrace or pause a bit. Use when quit game.
void I_WaitVBL(int count)
{
for ( ; count > 0; count--)
WaitTOF();
}
/**********************************************************************/
void I_ReadScreen (byte* scr)
{
UBYTE *base_address;
if (video_is_directcgx)
if (video_bitmap_is_locked) {
UnLockBitMap (video_bitmap_handle);
ReadPixelArray8 (video_window->RPort, 0,
video_which != 0 ? video_oscan_height : 0,
SCREENWIDTH-1, SCREENHEIGHT-1, scr, &video_temprp);
video_bitmap_handle = LockBitMapTags (video_screen->ViewPort.RasInfo->BitMap,
LBMI_BASEADDRESS, &base_address,
TAG_DONE);
if (video_which != 0)
screens[0] = base_address + (SCREENWIDTH * video_oscan_height);
else
screens[0] = base_address;
R_InitBuffer (scaledviewwidth, viewheight); /* recalc ylookup2[] */
} else
ReadPixelArray8 (video_window->RPort, 0,
video_which != 0 ? video_oscan_height : 0,
SCREENWIDTH-1, SCREENHEIGHT-1, scr, &video_temprp);
else
memcpy (scr, screens[0], SCREENWIDTH * SCREENHEIGHT);
}
/**********************************************************************/
void I_BeginRead (void)
{
}
/**********************************************************************/
void I_EndRead (void)
{
}
/**********************************************************************/
int xlate_key (UWORD rawkey, UWORD qualifier, APTR *eventptr)
{
char buffer[4], c;
struct InputEvent ie;
static int xlate[0x68] = {
'`', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', KEY_MINUS, KEY_EQUALS, '\\', 0, '0',
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', KEY_F11, KEY_F12, 0, '0', '2', '3',
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k',
'l', ';', '\'', KEY_ENTER, 0, '4', '5', '6',
KEY_RSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm',
',', '.', '/', 0, '.', '7', '8', '9',
' ', KEY_BACKSPACE, KEY_TAB, KEY_ENTER, KEY_ENTER, KEY_ESCAPE, KEY_F11,
0, 0, 0, KEY_MINUS, 0, KEY_UPARROW, KEY_DOWNARROW, KEY_RIGHTARROW, KEY_LEFTARROW,
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8,
KEY_F9, KEY_F10, '(', ')', '/', '*', KEY_EQUALS, KEY_PAUSE,
KEY_RSHIFT, KEY_RSHIFT, 0, KEY_RCTRL, KEY_LALT, KEY_RALT, 0, KEY_RCTRL
};
if (video_is_rawkey)
if (rawkey < 0x68)
return xlate[rawkey];
else
return 0;
else
if (rawkey > 0x00 && rawkey < 0x0a) // '1'..'9', no SHIFT French keyboards
return '0' + rawkey;
else if (rawkey == 0x0a) // '0'
return '0';
else if (rawkey < 0x40) {
ie.ie_Class = IECLASS_RAWKEY;
ie.ie_Code = rawkey;
ie.ie_Qualifier = qualifier;
ie.ie_EventAddress = *eventptr;
if (MapRawKey (&ie, buffer, sizeof(buffer), NULL) > 0) {
c = buffer[0];
if (c >= '0' && c <= '9') /* numeric pad */
switch (c) {
case '0':
return ' ';
case '1':
return ',';
case '2':
return KEY_RCTRL;
case '3':
return '.';
case '4':
return KEY_LEFTARROW;
case '5':
return KEY_DOWNARROW;
case '6':
return KEY_RIGHTARROW;
case '7':
return ',';
case '8':
return KEY_UPARROW;
case '9':
return '.';
}
else if (c >= 'A' && c <= 'Z')
return c - 'A' + 'a';
else if (c == '<')
return ',';
else if (c == '>')
return '.';
else if (c == '-')
return KEY_MINUS;
else if (c == '=')
return KEY_EQUALS;
else if (c == '[')
return KEY_F11;
else if (c == ']')
return KEY_F12;
else if (c == '\r')
return KEY_ENTER;
else if (c == '\n')
return KEY_ENTER;
else
return c;
} else
return 0;
} else if (rawkey < 0x68)
return xlate[rawkey];
else
return 0;
}
/**********************************************************************/
void amiga_getevents (void)
{
event_t event;
ULONG class;
UWORD code;
WORD mousex, mousey;
struct IntuiMessage *msg;
static ULONG previous = 0;
static event_t joyevent = {0}, mouseevent = {0};
ULONG currSega;
int doomkey;
if (video_window != NULL) {
while ((msg = (struct IntuiMessage *)GetMsg (video_window->UserPort)) != NULL) {
class = msg->Class;
code = msg->Code;
mousex = msg->MouseX;
mousey = msg->MouseY;
if (class == IDCMP_RAWKEY) {
if ((code & 0x80) != 0) {
code &= ~0x80;
event.type = ev_keyup;
} else {
event.type = ev_keydown;
}
if (code < 0x68)
doomkey = xlate_key (code, msg->Qualifier, msg->IAddress);
}
ReplyMsg ((struct Message *)msg); /* reply after xlating key */
if (class == IDCMP_RAWKEY) {
if (code < 0x68 && doomkey != 0) {
event.data1 = doomkey;
D_PostEvent (&event);
/* printf ("key %02x -> %02x\n", code, doomkey); */
}
} else if (class == IDCMP_MOUSEMOVE) {
mouseevent.type = ev_mouse;
mouseevent.data2 = (mousex << 3);
mouseevent.data3 = -(mousey << 5);
D_PostEvent (&mouseevent);
} else if (class == IDCMP_MOUSEBUTTONS) {
mouseevent.type = ev_mouse;
switch (code) {
case SELECTDOWN:
mouseevent.data1 |= 1;
break;
case SELECTUP:
mouseevent.data1 &= ~1;
break;
case MENUDOWN:
mouseevent.data1 |= 2;
break;
case MENUUP:
mouseevent.data1 &= ~2;
break;
case MIDDLEDOWN:
mouseevent.data1 |= 4;
break;
case MIDDLEUP:
mouseevent.data1 &= ~4;
break;
default:
break;
}
D_PostEvent (&mouseevent);
}
}
}
if (gameport_is_open && gameport_io_in_progress) {
while (GetMsg (gameport_mp) != NULL) {
switch (gameport_ie.ie_Code) {
case IECODE_LBUTTON:
joyevent.data1 |= 1;
break;
case IECODE_LBUTTON | IECODE_UP_PREFIX:
joyevent.data1 &= ~1;
break;
case IECODE_RBUTTON:
joyevent.data1 |= 2;
break;
case IECODE_RBUTTON | IECODE_UP_PREFIX:
joyevent.data1 &= ~2;
break;
case IECODE_MBUTTON:
joyevent.data1 |= 4;
break;
case IECODE_MBUTTON | IECODE_UP_PREFIX:
joyevent.data1 &= ~4;
break;
case IECODE_NOBUTTON:
joyevent.data2 = gameport_ie.ie_X;
joyevent.data3 = gameport_ie.ie_Y;
break;
default:
break;
}
joyevent.type = ev_joystick;
D_PostEvent (&joyevent);
gameport_io->io_Command = GPD_READEVENT;
gameport_io->io_Length = sizeof (struct InputEvent);
gameport_io->io_Data = &gameport_ie;
SendIO ((struct IORequest *)gameport_io);
}
}
/* CD32 joypad handler code supplied by Gabry (ggreco@iol.it) */
if (LowLevelBase != NULL) {
event_t joyevent;
ULONG joypos = ReadJoyPort (1);
if (previous == joypos)
return;
joyevent.type = ev_joystick;
joyevent.data1 = joyevent.data2 = joyevent.data3 = 0;
if (joypos & JPF_BUTTON_RED)
joyevent.data1 |= 1;
else
joyevent.data1 &= ~1;
if (joypos & JP_DIRECTION_MASK) {
if (joypos & JPF_JOY_LEFT) {
joyevent.data2 = -1;
} else if (joypos & JPF_JOY_RIGHT) {
joyevent.data2 = 1;
}
if (joypos & JPF_JOY_UP) {
joyevent.data3 = -1;
} else if (joypos & JPF_JOY_DOWN) {
joyevent.data3 = 1;
}
}
if (joypos & JP_TYPE_GAMECTLR) {
event_t event;
// Play/Pause = ESC (Menu)
if (joypos & JPF_BUTTON_PLAY && !(previous & JPF_BUTTON_PLAY)) {
event.type = ev_keydown;
event.data1 = KEY_ESCAPE;
D_PostEvent (&event);
} else if (previous & JPF_BUTTON_PLAY) {
event.type = ev_keyup;
event.data1 = KEY_ESCAPE;
D_PostEvent (&event);
}
// YELLOW = SHIFT (button 2) (Run)
if (joypos & JPF_BUTTON_YELLOW)
joyevent.data1 |= 4;
else
joyevent.data1 &= ~4;
// BLUE = SPACE (button 3) (Open/Operate)
if (joypos & JPF_BUTTON_BLUE)
joyevent.data1 |= 8;
else
joyevent.data1 &= ~8;
// GREEN = RETURN (show msg)
if (joypos & JPF_BUTTON_GREEN && !(previous&JPF_BUTTON_GREEN)) {
event.type = ev_keydown;
event.data1 = 13;
D_PostEvent (&event);
} else if (previous & JPF_BUTTON_GREEN) {
event.type = ev_keyup;
event.data1 = 13;
D_PostEvent (&event);
}
// FORWARD & REVERSE - ALT (Button1) Strafe left/right
if (joypos & JPF_BUTTON_FORWARD) {
joyevent.data1 |= 2;
joyevent.data2 = 1;
} else if (joypos & JPF_BUTTON_REVERSE) {
joyevent.data1 |=2;
joyevent.data2=-1;
} else
joyevent.data1 &= ~2;
}
D_PostEvent (&joyevent);
previous = joypos;
}
/* SEGA joypad handler code by Joe Fenton, loosely based on CD32 handling */
if (sega3_selected || sega6_selected) {
event_t joyevent, event;
if (sega3_selected) {
currSega = Sega3 ();
} else {
currSega = Sega6 ();
}
if (prevSega == currSega)
return;
joyevent.type = ev_joystick;
joyevent.data1 = joyevent.data2 = joyevent.data3 = 0;
// B = fire
if (currSega & 0x10)
joyevent.data1 |= 1;
else
joyevent.data1 &= ~1;
// directionals
if (currSega & 0xF) {
if (currSega & 4) {
joyevent.data2 = -1;
} else if (currSega & 8) {
joyevent.data2 = 1;
}
if (currSega & 1) {
joyevent.data3 = -1;
} else if (currSega & 2) {
joyevent.data3 = 1;
}
}
// Mode = ESC (Menu)
if (currSega & 0x80000 && !(prevSega & 0x80000)) {
event.type = ev_keydown;
event.data1 = KEY_ESCAPE;
D_PostEvent (&event);
} else if (prevSega & 0x80000) {
event.type = ev_keyup;
event.data1 = KEY_ESCAPE;
D_PostEvent (&event);
}
// Y = SHIFT (Run)
if (currSega & 0x20000)
joyevent.data1 |= 4;
else
joyevent.data1 &= ~4;
// Start = SPACE (Open/Operate)
if (currSega & 0x2000)
joyevent.data1 |= 8;
else
joyevent.data1 &= ~8;
// A & C - ALT (Button1) Strafe left/right
if (currSega & 0x20) {
joyevent.data1 |= 2;
joyevent.data2 = 1;
} else if (currSega & 0x1000) {
joyevent.data1 |=2;
joyevent.data2=-1;
} else
joyevent.data1 &= ~2;
// X = RETURN (show msg)
if (currSega & 0x40000 && !(prevSega&0x40000)) {
event.type = ev_keydown;
event.data1 = 13;
D_PostEvent (&event);
} else if (prevSega & 0x40000) {
event.type = ev_keyup;
event.data1 = 13;
D_PostEvent (&event);
}
// Z = TAB (show map)
if (currSega & 0x10000 && !(prevSega&0x10000)) {
event.type = ev_keydown;
event.data1 = 9;
D_PostEvent (&event);
} else if (prevSega & 0x10000) {
event.type = ev_keyup;
event.data1 = 9;
D_PostEvent (&event);
}
D_PostEvent (&joyevent);
prevSega = currSega;
}
}
/**********************************************************************/
static void calc_time (ULONG time, char *msg)
{
printf ("Total %s = %u us (%u us/frame)\n", msg,
(ULONG)(1000000.0 * ((double)time) / ((double)eclocks_per_second)),
(ULONG)(1000000.0 * ((double)time) / ((double)eclocks_per_second) /
((double)total_frames)));
}
/**********************************************************************/
void _STDvideo_cleanup (void)
{
I_ShutdownGraphics ();
if (video_smr != NULL) {
FreeAslRequest (video_smr);
video_smr = NULL;
}
/* printf ("EClocks per second = %d\n", eclocks_per_second); */
if (total_frames > 0) {
printf ("Total number of frames = %u\n", total_frames);
calc_time (blit_time, "blit wait time ");
calc_time (safe_time, "safe wait time ");
calc_time (c2p_time, "Chunky2Planar time ");
calc_time (ccs_time, "CopyChunkyScreen time ");
calc_time (wpa8_time, "WritePixelArray8 time ");
calc_time (lock_time, "LockBitMap time ");
}
}
/**********************************************************************/